package beautiful.butterfly.drds.data_exchange.transport.record.column;

import beautiful.butterfly.drds.data_exchange.exception.CommonErrorCode;
import beautiful.butterfly.drds.data_exchange.exception.DataExchangeException;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Date;

public class DoubleColumn extends Column
{

    public DoubleColumn(final String string)
    {
        this(string, null == string ? 0 : string.length());
        this.validate(string);
    }

    public DoubleColumn(Long aLong)
    {
        this(aLong == null ? (String) null : String.valueOf(aLong));
    }

    public DoubleColumn(Integer integer)
    {
        this(integer == null ? (String) null : String.valueOf(integer));
    }

    /**
     * Double无法表示准确的小数数据，我们不推荐使用该方法保存Double数据，建议使用String作为构造入参
     */
    public DoubleColumn(final Double aDouble)
    {
        this(aDouble == null ? (String) null
                : new BigDecimal(String.valueOf(aDouble)).toPlainString());
    }

    /**
     * Float无法表示准确的小数数据，我们不推荐使用该方法保存Float数据，建议使用String作为构造入参
     */
    public DoubleColumn(final Float aFloat)
    {
        this(aFloat == null ? (String) null
                : new BigDecimal(String.valueOf(aFloat)).toPlainString());
    }

    public DoubleColumn(final BigDecimal string)
    {
        this(null == string ? (String) null : string.toPlainString());
    }

    public DoubleColumn(final BigInteger string)
    {
        this(null == string ? (String) null : string.toString());
    }

    public DoubleColumn()
    {
        this((String) null);
    }

    private DoubleColumn(final String string, int byteSize)
    {
        //底层类型是string
        super(string, ColumnType.DOUBLE, byteSize);
    }


    @Override
    public Boolean asBoolean()
    {
        throw DataExchangeException.asDataExchangeException(
                CommonErrorCode.CONVERT_NOT_SUPPORT, "Double类型无法转为Bool .");
    }

    @Override
    public Long asLong()
    {
        if (null == this.getObject())
        {
            return null;
        }

        BigDecimal bigDecimal = this.asBigDecimal();
        OverFlowChecker.validateDataIsNotOverFlowLongRange(bigDecimal.toBigInteger());

        return bigDecimal.longValue();
    }

    @Override
    public Double asDouble()
    {
        if (null == this.getObject())
        {
            return null;
        }

        String string = (String) this.getObject();

        boolean isDoubleSpecific = string.equals("NaN") || string.equals("-Infinity") || string.equals("+Infinity");
        if (isDoubleSpecific)
        {
            return Double.valueOf(string);
        }

        BigDecimal bigDecimal = this.asBigDecimal();
        OverFlowChecker.validateDataIsNotOverFlowDoubleRange(bigDecimal);

        return bigDecimal.doubleValue();
    }


    @Override
    public BigDecimal asBigDecimal()
    {
        if (null == this.getObject())
        {
            return null;
        }

        try
        {
            return new BigDecimal((String) this.getObject());
        } catch (NumberFormatException e)
        {
            throw DataExchangeException.asDataExchangeException(
                    CommonErrorCode.CONVERT_NOT_SUPPORT,
                    String.format("String[%s] 无法转换为Double类型 .",
                            (String) this.getObject()));
        }
    }

    @Override
    public BigInteger asBigInteger()
    {
        if (null == this.getObject())
        {
            return null;
        }

        return this.asBigDecimal().toBigInteger();
    }

    @Override
    public String asString()
    {
        if (null == this.getObject())
        {
            return null;
        }
        return (String) this.getObject();
    }


    @Override
    public Date asDate()
    {
        throw DataExchangeException.asDataExchangeException(
                CommonErrorCode.CONVERT_NOT_SUPPORT, "Double类型无法转为Date类型 .");
    }

    @Override
    public byte[] asBytes()
    {
        throw DataExchangeException.asDataExchangeException(
                CommonErrorCode.CONVERT_NOT_SUPPORT, "Double类型无法转为Bytes类型 .");
    }

    private void validate(final String string)
    {
        if (null == string)
        {
            return;
        }

        if (string.equalsIgnoreCase("NaN") || string.equalsIgnoreCase("-Infinity") || string.equalsIgnoreCase("Infinity"))
        {
            return;
        }

        try
        {
            new BigDecimal(string);
        } catch (Exception e)
        {
            throw DataExchangeException.asDataExchangeException(
                    CommonErrorCode.CONVERT_NOT_SUPPORT,
                    String.format("String[%s]无法转为Double类型 .", string));
        }
    }

}